﻿using System;
using System.IO;

using InputFileGenerator;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace InputFileGeneratorTest
{
    /// <summary>
    /// Summary description for GraphModelsFileCreationTest
    /// </summary>
    [TestClass]
    public class GraphModelsFileCreationTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }
        //                                {0}        {1}          {2}                               {3}                              {4}      {5}       {6}       {7}       {8}       {9}
        private string[] smallArgs =  { "-name", "graphmodels", "-file", "C:\\DWARFS2\\Bin\\InputFileGenerator\\smallContent.txt" , "-size", "500" , "-states", "2000", "-sequence", "300" };
        private string[] mediumArgs = { "-name", "graphmodels", "-file", "C:\\DWARFS2\\Bin\\InputFileGenerator\\mediumContent.txt", "-size", "1000", "-states", "4000", "-sequence", "500" };
        private string[] largeArgs =  { "-name", "graphmodels", "-file", "C:\\DWARFS2\\Bin\\InputFileGenerator\\largeContent.txt" , "-size", "2000", "-states", "7000", "-sequence", "700" };

        private bool IsFileCareful(string[] args)
        {
            if (!File.Exists(args[3]))
            {
                return false;
            }

            return IsFormatCareful(args); 
            
        }
        private bool IsFormatCareful(string[] args)
        {
            bool returnval = false;
            FileStream stream = null;
            StreamReader reader = null;
            try
            {
                stream = new FileStream(args[3], FileMode.Open, FileAccess.Read, FileShare.Read);
                reader = new StreamReader(stream);

                int observations = int.Parse(reader.ReadLine().Split(':')[1]);
                int expectedObs = int.Parse(args[5]);

                if (observations != expectedObs)
                {
                    throw new Exception("Incorrect matrix dimension.");
                }

                int states = int.Parse(reader.ReadLine().Split(':')[1]);
                int expectedStates = int.Parse(args[7]);

                if (states != expectedStates)
                {
                    throw new Exception("Incorrect matrix dimension.");
                }

                reader.ReadLine();                                  // leave out empty line     

                // check the state transition matrix
                if (!MatrixHelper.IsMatrixCareful(reader, observations, observations, TypeElement.DOUBLE))
                {
                    throw new Exception("Incorrect structure of transition matrix.");
                }

                reader.ReadLine();                                  // leave out empty line

                // check the odservation probability matrix
                if (!MatrixHelper.IsMatrixCareful(reader, observations, states, TypeElement.DOUBLE))
                {
                    throw new Exception("Incorrect structure of odservation probability matrix.");
                }

                reader.ReadLine();                                  // leave out empty line

                // check the initial states list
                if (!MatrixHelper.IsMatrixCareful(reader, observations, 1, TypeElement.DOUBLE))
                {
                    throw new Exception("Incorrect structure of initial states list.");
                }

                reader.ReadLine();                                  // leave out empty line

                int sequence = int.Parse(reader.ReadLine().Split(':')[1]);
                int expectedSequence = int.Parse(args[9]);

                if (sequence != expectedSequence)
                {
                    throw new Exception("Incorrect sequence dimension.");
                }

                reader.ReadLine();                                  // leave out empty line 

                if (!MatrixHelper.IsMatrixCareful(reader, sequence, 1, TypeElement.INT ))
                {
                    throw new Exception("Incorrect matrix dimension.");
                }

                returnval = true;
            }
            catch (Exception e)
            {
                Console.Out.WriteLine(e.ToString());
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }

            return returnval;
        }

        /// <summary>
        ///A test for Graph Models generation process
        ///</summary>
        [TestMethod()]
        [DeploymentItem("InputFileGenerator.exe")]
        public void MainTest()
        {
            string[] args = smallArgs;

            //test for small 
            Program_Accessor.Main(args);
            Assert.IsTrue(IsFileCareful(args));

            args = mediumArgs;

            //test for medium 
            Program_Accessor.Main(args);
            Assert.IsTrue(IsFileCareful(args));

            args = largeArgs;

            //test for large 
            Program_Accessor.Main(args);
            Assert.IsTrue(IsFileCareful(args));

        }
    }
}
